import logging
import os
from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QLabel, QTableWidget, QTableWidgetItem, QHBoxLayout, 
                           QHeaderView, QAbstractItemView, QPushButton, QLineEdit, QFileDialog, 
                           QGroupBox, QMessageBox)
from PyQt5.QtCore import Qt
from frame_processor import FrameProcessor
from progress_dialog import ProgressDialog
from file_loader_thread import FileLoaderThread
from utils import get_resource_path
from logger import logger
from visualization_functions import create_frame_stats_plot

class AnalyzeWidget(QWidget):
    """文件分析界面组件"""

    def __init__(self, parent=None):
        super().__init__(parent)
        self.layout = QVBoxLayout()
        self.logger = logging.getLogger('frame_analyzer')
        schema_file = get_resource_path('frame_schema.xml')
        self.frame_processor = FrameProcessor(schema_file)
        self.current_stats = None
        
        # 设置通用样式
        self.setStyleSheet("""
            QTableWidget {
                gridline-color: #DDDDDD;
                background-color: white;
                alternate-background-color: #E3F2FD;  /* 浅蓝色背景 */
                selection-background-color: #2196F3;  /* 选中时的深蓝色 */
                selection-color: white;
            }
            QHeaderView::section {
                background-color: #1976D2;  /* 深蓝色表头背景 */
                color: white;  /* 表头文字颜色 */
                padding: 6px;
                border: none;
                font-weight: bold;
            }
            QHeaderView::section:checked {
                background-color: #1565C0;  /* 选中时更深的蓝色 */
            }
            QGroupBox {
                border: 1px solid #BBBBBB;
                border-radius: 5px;
                margin-top: 10px;
                padding-top: 12px;
                font-weight: bold;
            }
            QGroupBox::title {
                subcontrol-origin: margin;
                subcontrol-position: top center;
                padding: 0 5px;
            }
        """)

        # 文件选择区域
        file_group = QGroupBox("文件选择")
        
        file_layout = QHBoxLayout()

        self.file_path = QLineEdit()
        self.file_path.setReadOnly(True)
        self.file_path.setPlaceholderText("选择要分析的文件")
        self.file_btn = QPushButton("浏览...")
        self.file_btn.clicked.connect(self._select_file)

        file_layout.addWidget(QLabel("文件:"))
        file_layout.addWidget(self.file_path)
        file_layout.addWidget(self.file_btn)

        file_group.setLayout(file_layout)
        self.layout.addWidget(file_group)

        # 操作按钮区域
        button_layout = QHBoxLayout()

        # 分析按钮
        self.analyze_button = QPushButton("开始分析")
        self.analyze_button.setEnabled(False)
        self.analyze_button.setStyleSheet("""
            QPushButton {
                background-color: #0064c8;
                color: white;
                border: none;
                padding: 10px 20px;
                font-size: 14px;
                font-weight: bold;
                border-radius: 5px;
                min-width: 150px;
            }
            QPushButton:disabled {
                background-color: #cccccc;
            }
            QPushButton:hover:!disabled {
                background-color: #0055a5;
            }
            QPushButton:pressed:!disabled {
                background-color: #00448a;
            }
        """)

        button_layout.addStretch()
        button_layout.addWidget(self.analyze_button)
        button_layout.addStretch()
        self.layout.addLayout(button_layout)

        # 创建空的统计显示区域
        self.result_widget = create_frame_stats_plot({
            'total_frames': 0,
            'virtual_channels': {},
            'decode_status': {},
            'vc_counters': {},
            'detailed_stats': {
                'frame_count_stats': {'min': 0, 'max': 0},
                'virtual_channel_stats': {'active_channels': 0}  # 添加缺失的virtual_channel_stats
            }
        }, [])
        # 手动隐藏详细统计信息
        self.result_widget.stats_label.hide()
        self.result_widget.stats_text.hide()
        self.layout.addWidget(self.result_widget)

        self.setLayout(self.layout)

        # 连接信号
        self.analyze_button.clicked.connect(self._on_analyze_clicked)
        self.file_path.textChanged.connect(self._update_analyze_button_state)
        
        # 设置所有表格为不可编辑状态
        if hasattr(self, 'frame_table'):
            self.frame_table.setEditTriggers(QAbstractItemView.NoEditTriggers)
            # 启用交替行颜色
            self.frame_table.setAlternatingRowColors(True)

    def _select_file(self):
        """选择文件"""
        file_path, _ = QFileDialog.getOpenFileName(
            self,
            "选择文件",
            "",
            "帧数据文件 (*.raw *.dat);;XML文件 (*.xml);;所有文件 (*.*)"
        )
        if file_path:
            self.file_path.setText(file_path)

    def _update_analyze_button_state(self):
        """更新分析按钮状态"""
        has_file = bool(self.file_path.text())
        self.analyze_button.setEnabled(has_file)

    def _on_analyze_clicked(self):
        """执行分析操作"""
        try:
            # 获取文件路径
            file_path = self.file_path.text()

            if not file_path:
                QMessageBox.warning(self, "警告", "请选择需要分析的文件")
                return

            # 创建进度对话框
            progress = ProgressDialog(self)
            progress.setWindowTitle("正在分析文件")
            progress.show()

            # 创建文件加载线程
            self.loader_thread = FileLoaderThread(self.frame_processor, file_path)

            # 连接信号
            self.loader_thread.progress_signal.connect(
                lambda value, status, detail: progress.update_progress(value, status, detail)
            )

            # 处理完成信号
            def on_load_finished(frames):
                try:
                    # 分析帧数据
                    progress.update_progress(60, "正在分析数据...")
                    self.current_stats = self.frame_processor.analyze_frames(frames, file_path)
                    self.frames = frames  # 保存帧数据供后续使用

                    # 创建新的显示
                    progress.update_progress(90, "正在生成显示...")

                    # 清除旧的显示
                    if self.result_widget:
                        self.result_widget.setParent(None)

                    # 创建新的显示 - 使用全部帧数据，分页显示功能会自动处理
                    self.result_widget = create_frame_stats_plot(self.current_stats, frames)
                    self.layout.addWidget(self.result_widget)

                    progress.update_progress(100, "处理完成")
                    # 延迟关闭进度对话框，确保界面渲染完成
                    progress.complete_and_close()
                    
                    # 显示帧格式信息
                    frame_format = "未知"
                    frame_size = 0
                    if frames and len(frames) > 0:
                        # 检查第一个帧的类型
                        first_frame = frames[0]
                        if 'frame_len' in first_frame:
                            frame_size = first_frame['frame_len']
                            if frame_size == 1024:
                                frame_format = "1024字节 (0x1ACFFC1D)"
                            elif frame_size == 1092:
                                frame_format = "1092字节"
                        
                        # 如果可以获取同步字，显示同步字信息
                        if 'sync_word' in first_frame:
                            sync_word_hex = format(first_frame['sync_word'], '08X')
                            if sync_word_hex == "1ACFFC1D":
                                frame_format = "1024字节 (帧同步头: 0x1ACFFC1D)"
                            elif first_frame['sync_word'] == 1234567890:
                                frame_format = "1092字节 (帧头: 1234567890)"
                    
                    # 显示额外的帧信息
                    if frame_format != "未知":
                        QMessageBox.information(
                            self,
                            "分析完成",
                            f"文件分析完成\n"
                            f"检测到帧格式: {frame_format}\n"
                            f"总帧数: {len(frames)}\n"
                            f"错误帧已优先显示"
                        )
                except Exception as e:
                    self.logger.error(f"处理分析结果时出错: {str(e)}", exc_info=True)
                    progress.close()
                    QMessageBox.critical(self, "错误", f"处理分析结果时出错: {str(e)}")

            # 处理错误信号
            def on_load_error(error_msg):
                progress.close()
                QMessageBox.critical(self, "错误", f"分析文件失败: {error_msg}")

            # 处理取消操作
            def on_cancel_requested():
                self.loader_thread.cancel()

            # 连接信号
            self.loader_thread.finished_signal.connect(on_load_finished)
            self.loader_thread.error_signal.connect(on_load_error)
            progress.canceled.connect(on_cancel_requested)

            # 开始加载
            self.loader_thread.start()

        except Exception as e:
            self.logger.error(f"分析文件失败: {str(e)}")
            QMessageBox.critical(self, "错误", f"分析文件失败: {str(e)}")

    def _update_frame_table(self):
        """更新帧选择表格"""
        self.frame_table.setRowCount(len(self.frames))
        for i, frame in enumerate(self.frames):
            # 帧序号
            self.frame_table.setItem(i, 0, QTableWidgetItem(str(i)))
            # 帧计数 - 显示为十六进制，每两位一个空格
            self.frame_table.setItem(i, 1, QTableWidgetItem(format_hex_with_space(frame['frame_count'])))
            # 虚拟信道
            self.frame_table.setItem(i, 2, QTableWidgetItem(f"VC{frame['virtual_channel']}"))

            # 译码状态说明
            frame_check_decode = frame['decode_status']
            # 检查帧检验结果字段是否存在
            frame_check_result = frame.get('帧检验结果', 0)  # 如果不存在，使用默认值0
            status_text = []

            # 获取帧检验&译码状态的Bit 0和Bit 4
            bit0_value = frame_check_decode & 0x01
            bit4_value = (frame_check_decode >> 4) & 0x01

            if frame_check_decode == 0:
                status_text.append("无R-S译码")
            else:
                # 当RS译码开启时（Bit0=1），检查RS译码正确性
                if bit0_value == 1:
                    rs_error_bit = (frame_check_result >> 24) & 0x01  # 获取Byte0的bit0
                    if rs_error_bit == 0:
                        status_text.append("RS译码正确")
                    elif rs_error_bit == 1:
                        status_text.append("RS译码错误")
                    else:
                        status_text.append("RS译码无效")

                # 当LDPC译码开启时（Bit4=1），检查LDPC译码状态
                if bit4_value == 1:
                    ldpc_status_byte = (frame_check_result >> 24) & 0xFF  # 获取Byte0
                    if ldpc_status_byte == 0x00:
                        status_text.append("LDPC译码正确")
                    elif ldpc_status_byte == 0x01:
                        status_text.append("LDPC译码失败")
                    elif ldpc_status_byte == 0x02:
                        status_text.append("帧校验开且帧校验错误")
                    else:
                        # 直接在状态文本中显示具体状态值，不写入日志
                        ldpc_info = f"LDPC译码无效(0x{ldpc_status_byte:02X})"
                        status_text.append(ldpc_info)
            
            # 如果没有任何映射值，显示原始状态值
            if not status_text:
                # 直接在状态文本中显示具体状态值，不写入日志
                status_desc = f"未知译码状态(0x{frame_check_decode:02X}, Bit0={bit0_value}, Bit4={bit4_value})"
                status_text.append(status_desc)

            self.frame_table.setItem(i, 3, QTableWidgetItem(", ".join(status_text)))

            # 为空闲帧添加背景色
            if frame['virtual_channel'] == 0b111111:
                for col in range(4):
                    item = self.frame_table.item(i, col)
                    if item:
                        item.setBackground(Qt.lightGray)

        # 调整表格列宽
        self.frame_table.resizeColumnsToContents()

        # 更新分析按钮状态
        self.analyze_button.setEnabled(len(self.frames) > 0)

    def _on_frame_selected(self):
        """处理帧选择事件"""
        selected_rows = self.frame_table.selectedItems()
        if selected_rows:
            # 获取选中的行索引
            row = selected_rows[0].row()
            self.selected_frame_index = row

            # 获取所选帧
            frame = self.frames[row]

            # 更新帧详细信息
            info_text = (
                f"帧序号: {row}\n"
                f"帧计数: {frame['frame_count']}\n"
                f"虚拟信道: {frame['virtual_channel']}\n"
                f"译码状态: {self.frame_table.item(row, 3).text()}\n"
                f"帧长度: {len(frame['payload'])} 字节"
            )
            self.frame_info.setText(info_text)

            # 更新按钮状态
            self.analyze_button.setEnabled(True)
        else:
            self.selected_frame_index = None
            self.frame_info.clear()
            self.analyze_button.setEnabled(False)

    def _apply_filter(self, filter_text):
        """应用虚拟信道过滤"""
        if not filter_text:
            # 如果过滤文本为空，显示所有行
            for i in range(self.frame_table.rowCount()):
                self.frame_table.setRowHidden(i, False)
            return

        try:
            # 解析过滤文本，支持逗号分隔的多个虚拟信道号
            vc_filters = [int(vc.strip()) for vc in filter_text.split(',') if vc.strip()]

            # 遍历所有行，隐藏不匹配的行
            for i in range(self.frame_table.rowCount()):
                vc_item = self.frame_table.item(i, 2)
                if vc_item:
                    vc_text = vc_item.text().replace('VC', '')
                    try:
                        vc_value = int(vc_text)
                        # 如果当前行的虚拟信道不在过滤列表中，则隐藏它
                        self.frame_table.setRowHidden(i, vc_value not in vc_filters)
                    except ValueError:
                        # 如果无法解析为整数，显示该行
                        self.frame_table.setRowHidden(i, False)

        except Exception as e:
            self.logger.error(f"应用过滤器时发生错误: {str(e)}")
            # 出错时显示所有行
            for i in range(self.frame_table.rowCount()):
                self.frame_table.setRowHidden(i, False)

    def _get_compare_ranges(self):
        """获取要比较的字节范围"""
        if self.mode_data_only.isChecked():
            # 数据域：82-959字节
            return [(82, 959)]
        elif self.mode_header_data.isChecked():
            # 帧同步头+数据域
            return [(64, 67), (82, 959)]
        elif self.mode_custom.isChecked():
            # 自定义范围
            custom_text = self.custom_bytes_input.text().strip()
            if not custom_text:
                return []

            try:
                ranges = []
                # 解析逗号分隔的范围表达式，例如 "64-67,82-959"
                for range_text in custom_text.split(','):
                    if '-' in range_text:
                        start, end = map(int, range_text.split('-'))
                        if 0 <= start <= 1091 and 0 <= end <= 1091 and start <= end:
                            ranges.append((start, end))
                return ranges
            except Exception as e:
                self.logger.error(f"解析自定义字节范围时发生错误: {str(e)}")
                return []

        return []